const Restaurant = require("../model/restaurant.js");
const logger = require('../utils/logger')
const {transPromise, cPromise} = require('../utils/myPromise')
const {host} = require('../config')
const {translateUrlToAbsolute} = require('../utils')
const c = require('../utils/c')
const request = require('../utils/request')
const totalInfoHandle = require('../utils/totalInfoHandle')

/**
 * 上传图片到七牛
 * @type {UploadFile}
 */
const {UploadFiles} = require('../utils/upload')

const getBrandStory = url => {
  return new Promise((resolve, reject) => {
    if (url.length > 0) {
      cPromise(url).then($$ => {
        let brand = {
          mainPic: '',
          title: '',
          content: [],
          map: {
            name: '',
            location: ''
          }
        }
        //
        brand.mainPic = {
          text: $$('._3zrgJ46ouVPVD8zWaHX0l6 img').attr('title'),
          src: $$('._3zrgJ46ouVPVD8zWaHX0l6 img').attr('src'),
        }

        // title
        brand.title = {
          text: $$('._2AoqKUcdJHPd7RfPOmH1IW h1').text(),
          intro: $$('._2OpAl6NVxwk6F-NHqx4crJ ._2WVT_e39nAf0U6u77zRdcu').text(),
          time: $$('._2OpAl6NVxwk6F-NHqx4crJ ._1wBHFCdy5D4YZ-bDtYQxb_').text(),
        }


        // content
        $$('._198nXlXoiYBkCKbP5aX04J').children().each((k, v) => {
          let $v = $$(v)
          let tag = $v[0].tagName
          if (tag === 'p') {
            brand.content.push({
              tag: 'p',
              text: $v.text()
            })
          }


          if (tag === 'h2') {
            brand.content.push({
              tag: 'h2',
              seq: $v.find('.seq').text(),
              text: $v.find('b').text()
            })
          }

          if (tag === 'figure') {
            if ($v.find('img').attr('src')) {
              brand.content.push({
                tag: 'figure',
                src: $v.find('img').attr('src'),
                text: $v.find('figcaption').text()
              })
            }
          }


          if (tag === 'div') {
            let imgs = []
            $$(v).find('figure').each((key, value) => {
              if ($$(value).find('img')) {
                imgs.push({
                  src: $$(value).find('img').attr('src'),
                  text: $$(value).find('figcaption').text()
                })
              }
            })
            brand.content.push({
              tag: 'div',
              imgs: imgs
            })
          }
        })

        // map
        brand.map = {
          name: $$('._1MB1vj7GPnORlUNcPA-jBj').text(),
          location: $$('._3Ca2TqwtDlEJcEZrmPbZ_W ._3YPfNh8cCEjUf8VEeesPXU').html()
        }

        Promise.all(
          [
            transPromise($$('._2AoqKUcdJHPd7RfPOmH1IW h1').text(), url),
            transPromise($$('._2OpAl6NVxwk6F-NHqx4crJ ._2WVT_e39nAf0U6u77zRdcu').text(), url),
            transPromise($$('._2OpAl6NVxwk6F-NHqx4crJ ._1wBHFCdy5D4YZ-bDtYQxb_').text(), url)
          ]
        ).then(data => {
          brand.title = {
            text: data[0],
            intro: data[1],
            time: data[2],
          }
          let contentTransArr = []
          let contentTransIdx = []
          brand.content.forEach((v, k) => {
            let tag = v.tag
            if (tag === 'p') {
              contentTransArr.push(transPromise(v.text, url))
              contentTransIdx.push(k)
            }

            if (tag === 'h2') {
              contentTransArr.push(transPromise(v.text, url))
              contentTransIdx.push(k)
            }

            if (tag === 'figure') {
              contentTransArr.push(transPromise(v.text, url))
              contentTransIdx.push(k)
            }

          })

          Promise.all(contentTransArr).then(res => {
            // console.dir(res)
            res.forEach((v, k) => {
              brand.content[contentTransIdx[k]].text = v
            })
            resolve([brand])
          })
        })
      }, err => {
        logger.error(url, err)
        reject(err)
      })
    } else {
      resolve([])
    }
  })

}

const getComments = url => {
  return new Promise((resolve, reject) => {
    if (url) {
      cPromise(url).then($$ => {
        let comments = []
        $$('._2dqA-AeX5rEYvAafp6wc8b').each((k, v) => {
          let imgs = []
          $$(v).find('._2716ZqUMVcM6RrHa0msAAs img').each((key, value) => {
            let imgUrl = $$(value).attr('src')
            try {
              imgs.push({
                src: imgUrl.replace('/p/t/', '/p/l/'),
                thumb: imgUrl,
                text: $$(value).attr('title'),
              })
            } catch (e) {
              logger.error('parse src error', imgUrl)
            }

          })
          let comment = {
            name: $$(v).find('._3aotjlaKYspmt9vmnlkqRB a:first-child').text(),
            userName: $$(v).find('._3aotjlaKYspmt9vmnlkqRB>a').eq(0).text(),
            userImg: $$(v).find('._3aotjlaKYspmt9vmnlkqRB ._221SkqR5e4UgHCysTAG0lu img').attr('src'),
            start: $$(v).find('abbr').attr('title'),
            title: $$(v).find('._161zGspX5RpJZfcsL8prKB').text(),
            menu: $$(v).find('.GsxHDFebpThhJKCOkZCSI').text(),
            content: $$(v).find('._2PNaIYY2rOHsJp1nt9vZls').text(),
            imgs: imgs
          }
          comments.push(comment)
        })

        let arr = comments.map(item => transPromise([item.title, item.menu, item.content]))
        Promise
          .all(arr)
          .then(data => {
            let newComments = comments.concat([])
            data.forEach((v, k) => {
              newComments[k].title = v[0]
              newComments[k].menu = v[1]
              newComments[k].content = v[2]
            })
            resolve(newComments)
          }, err => {
            logger.error('爬取评论错误', err)
            resolve(err)
          })
      }, err => {
        logger.error(url, err)
        resolve(err)
      })
    } else {
      reject('评论为空')
    }
  })
}

const getMenus = url => {
  return new Promise((resolve, reject) => {
    cPromise(url + '/photos?page.number=1&page.size=3').then(data => {
      let imgs = []
      data('.wui-result img').each((k, v) => {
        imgs.push({
          src: data(v).attr('src'),
          title: data(v).attr('title')
        })
      })
      resolve(imgs)
    }, err => {
      logger.error(url, err)
      resolve(err)
    })
  })
}

const getImgs = url => {
  return new Promise((resolve, reject) => {
    let imgs = []
    let url1 = url+ '.json?_v=5.044&locale=th&type=13&page.size=10'
    let url2 = url+ '.json?_v=5.044&locale=th&type=14&page.size=10'
    request
      .get(url1)
      .end((err, res) => {
        if(err) {
          reject(err)
          totalInfoHandle.addError({
            url: url1,
            type:3
          })
        } else {

          res.body.page.entities.forEach(item => {
            imgs.push({
              src: item.thumbnailUrl.replace('/p/t/', '/p/l/'),
              thumb: item.thumbnailUrl,
              text: '',
              type: '13'
            })
          })

          totalInfoHandle.addSuccess({
            url: url1,
            type:3
          })

          request
            .get(url2)
            .end((err, res) => {
              if(err) {
                resolve(err)
                totalInfoHandle.addError({
                  url: url2,
                  type:3
                })
              } else {

                res.body.page.entities.forEach(item => {
                  imgs.push({
                    src: item.thumbnailUrl.replace('/p/t/', '/p/l/'),
                    thumb: item.thumbnailUrl,
                    text: '',
                    type: '14'
                  })
                })


                resolve(imgs)

                totalInfoHandle.addSuccess({
                  url: url2,
                  type:3
                })
              }
            });
        }
      });
  })
}

const getMenuRecommend = url => {
  return new Promise(resolve => {
    cPromise(url)
      .then($$ => {
        let promiseArr = []
        let promiseTansArr = []
        let tansArr = []
        let urls = []
        $$('.favouriteMenuItem a').each((k, v) => {
          urls.push(host + $$(v).attr('href'))
          tansArr.push($$(v).find('img').attr('title'))
        })

        promiseArr = urls.map(item => cPromise(item))
        promiseTansArr = tansArr.map(item => transPromise(item))

        Promise
          .all(promiseArr)
          .then(data => {
            let result = []
            data.forEach(item => {
              let imgs = []
              item('.photoC img').each((k, v) => {
                imgs.push({
                  src: item(v).attr('src'),
                  title: item(v).attr('title')
                })
              })
              result.push({
                name: item('.menuInfo .title').text(),
                imgs
              })
            })

            // 翻译
            Promise.all(
              promiseTansArr
            ).then(data => {
              data.forEach((v, k) => {
                result[k]['nameCn'] = v
              })
              resolve(result)
            })
          })

      }, err => {
          logger.error(url, err)
          resolve([])
        })
  })
}

const uploadDetailsImgs = (result, cb) => {
  let imgs = []
  let imgsUploads = []
  imgs.push({
    src: result.mainPic
  })

  result.menu.forEach(v => imgs.push(v))
  result.menuRecommend.forEach(v => imgs.concat(v.imgs))
  result.comments.forEach(v => {
    imgs = imgs.concat(v.imgs)
  })
  imgs = imgs.concat(result.imgs)

  result.brandStory.forEach(v => {

    if(v.content.length > 0) {
      imgs.push({
        src: v.mainPic.src
      })
      v.content.forEach(value => {
        if (value.tag === 'figure') {
          imgs.push({
            src: value.src
          })
        }

        if (value.tag === 'div') {
          value.imgs.forEach(value => {
            imgs.push({
              src: value.src
            })
          })
        }
      })
    }
  })
  logger.info('uploading restaurant imgs', result.url)

  imgs.map((item, k) => {
    let resUrl = ''
    if (item.src) {
      resUrl = translateUrlToAbsolute(item.src, host)
      let fileName = resUrl.split('/').pop()
      imgsUploads.push({
        resUrl,
        key: fileName,
      })

      if (item.thumb) {
        imgsUploads.push({
          resUrl: translateUrlToAbsolute(item.thumb, host),
          key: fileName.replace('.', '_s.'),
        })
      }
    } else {
      logger.error('uploading restaurant imgs src error!!!', JSON.stringify(item), result.url)
    }
  })

  UploadFiles(imgsUploads)
}

module.exports = (url, {regions = []}) => {
  logger.info(`crawling restaurant ${url}`)
  totalInfoHandle.add({
    type: 1,
    url
  })
	return new Promise(function (resolve, reject) {
		c.queue({
			uri: url,

      // rateLimit: 20000,
      // maxConnections: 1,
      // encoding: null,
      // retries:10,
      // retryTimeout: 1000,

			callback: (error, res, done) => {
				if (error) {
					logger.error(error.stack);
					totalInfoHandle.addError({
						type: 3,
						url
					})
          reject(error)
				}
				else {
					let $$ = res.$;
					let url = res.request.uri.href.split('?')[0]
					let imgsCrawlUrl = url + '/photos'
					let menuUrl = url + '/menu'
					let brandUrl = ''
					let commentUrl = ''
					let result = {
						url: url,
						baseInfo: null,
						name: '', // 点名
						nameCn: '', // 点名
						start: 0, // 评星
						gathered: false,
						collectionCount: 0, // 收藏数量
						classification: '', //分类
						mainPic: '', // 主图
						position: null, // 位置信息
						tel: '', // 电话
						menu: null, // 菜单
						menuRecommend: [], // 菜单
						special: [], // 特别（非必选）
						brandStory: [], // 特别（非必选）
						imgs: [], // 餐厅图片
						extraInfo: [], // 额外信息
						recommend: [], // 会员推荐
						fit: [], // 这家店适合
						comments: [], // 评论
						regions,
						commentsStart: {
							total: 0,
							all: []
						}, // 评论
					}

					try {
						result.baseInfo = JSON.parse($$('[type="application/ld+json"]').eq(1).text())
					} catch (e) {
						logger.error('parse restaurant baseInfo error')
						totalInfoHandle.addError({
							type: 3,
							url,
              err: e
						})
					}

					/**
					 * 获取基础数据
					 */

					result.name = $$('.rgC9s9h7rggFPcyM5PHFm').text();
					result.start = parseFloat($$('.Uj8mG2ERJ4cdell8DEPX1 abbr').attr('title'));
					result.collectionCount = parseInt($$('._3xSGEse2LYyLxKe3FXiPiI').text());
					result.mainPic = $$('img._1D0k0NdKyUhme8KI2ro0vm').attr('src');
					result.position = {
						name: $$('.TXRNAoL_vjvATWA1goNCX .JDKZ-lvAtKPUWPwxM2Zof').text(),
						location: $$('._3zeuFq-h9dwuIxYGs5eNh3 img').attr('srcset')
					};
					result.tel = $$('._25mNHgbvjNbmphiGyMB2B0').text()
					let classificationTai = [];
					$$('._2mVbrhhqwezGDwaukndhiz').each((k, v) => {
						classificationTai.push($$(v).text())
					})

					// special
					$$('._3QtlLM5aqRn0HR03XTdCIJ').each((k, v) => {
						result.special.push($$(v).text())
					})

					// extraInfo
					result.extraInfo = {
						extraInfoList: [],
						extraInfoGen: {
							price: '',
							site: '',
							time: ''
						}
					}

					$$('._1weidWQshSdU3oH6Fm7DNW').each((k, v) => {

						let list = $$(v).find('ul')

						if (list.length > 0) {

							$$(v).find('li').each((key, value) => {
								let text = $$(value).find('._2Kc89xSc7gyXlf6l0mPvTB').text()
								if ($$(value).find('._26F9acvXaVARlgOfLN7U18').length === 0) {
									result.extraInfo.extraInfoList.push(text)
								}
							})
						} else {
							if ($$(v).find('._2Kc89xSc7gyXlf6l0mPvTB').length > 0) {
								let text = $$(v).find('._2Kc89xSc7gyXlf6l0mPvTB').text()
								if ('ช่วงราคา' === text) { // 价格
									result.extraInfo.extraInfoGen.price = $$(v).find('._2Kc89xSc7gyXlf6l0mPvTB').next().next().text()
								} else if ('จำนวนที่นั่ง' === text) { // 座位
									result.extraInfo.extraInfoGen.site = $$(v).find('._2Kc89xSc7gyXlf6l0mPvTB').next().text()
								} else if ('เวลาเปิดร้าน' === text) { // 时间
									let t = $$(v).find('._2Kc89xSc7gyXlf6l0mPvTB').next().text().split(':')
									t.shift()
									result.extraInfo.extraInfoGen.time = t.join(':')
								}
							}
						}

					})

					let fitPercent = []
					$$('._1w0yG7J5LFgv_Bbhd1lHNv').each((k, v) => {
						// recommend
						if ($$(v).find('._1o6WlpIqZOEUiKAkfNLhc5 h2').text() === 'เมนูที่แนะนำโดยสมาชิก') {
							$$(v).find('.yysZOtv9226O_qnYp5rmT li').each((key, value) => {
								result.recommend.push($$(value).find('._2wQaLAzTta32eJwRNiFg-').text())
							})
						}

						// fit
						if ($$(v).find('._1o6WlpIqZOEUiKAkfNLhc5 h2').text() === 'ร้านนี้เหมาะกับ') {
							$$(v).find('._86owKJUwiOgzCSmspmHEt li').each((key, value) => {
								let text = $$(value).find('._3OrXzunt94A0UmhEShO5YG').text()
								if (text.length > 0) {
									result.fit.push(text.split('(')[0])
									fitPercent.push(text.split('(')[1].split(')')[0])
								}
							})
						}

						// commentStart
						if ($$(v).find('._1o6WlpIqZOEUiKAkfNLhc5 h2').text().indexOf('รีวิว') !== -1) {
							$$(v).find('._1qv4eOwcgCBIACmS4qhh5p').each((key, value) => {
								result.commentsStart.all.push($$(value).attr('title'))
							})
							result.commentsStart.total = $$(v).find('._3GJOnVk8EKPyhBqGUVmRXR').text().split(' ')[0]
							result.commentsStart.range = [$$(v).find('._1Ph2rdXQjvqVkIYvTbDA1F span').eq(0).text(), $$(v).find('._1Ph2rdXQjvqVkIYvTbDA1F span').eq(1).text()]


							commentUrl = host + $$(v).find('._3vrPGLotBqwV68SmNHuXR8').attr('href')
						}

						// brandStory
						if ($$(v).find('._1o6WlpIqZOEUiKAkfNLhc5 h2').text().indexOf('Brand Story') !== -1) {
							if ($$(v).find('.gzfBDhOlwKcTIm6u8ZirF a').length > 0) {
								brandUrl = host + $$(v).find('.gzfBDhOlwKcTIm6u8ZirF a').attr('href')
							} else {
								brandUrl = host + $$(v).find('li').eq(0).find('a').attr('href')
							}
						}

					})
					/**
					 * 翻译数据
					 */
					Promise
						.all([
							transPromise(classificationTai, url), // classification
							transPromise(result.special, url), // special
							transPromise(result.extraInfo.extraInfoList, url), //
							transPromise(result.recommend, url), //
							transPromise(result.fit, url), //
							getImgs(imgsCrawlUrl),
							getBrandStory(brandUrl),
							getComments(commentUrl, url),
							getMenus(menuUrl, url),
							transPromise(result.name, url),
							getMenuRecommend(menuUrl, url)
						])
						.then(data => {
							// 分类
							result.classification = data[0].join(',');
							//
							result.special = data[1]

							// extra
							result.extraInfo.extraInfoList = data[2]

							// recommend
							result.recommend = data[3]

							// fit
							result.fit = data[4].map((item, key) => {
								return item + ',' + fitPercent[key]
							})

							// 图片
							result.imgs = data[5]

              if(data[5].length === 0) {
                reject('imgs 为空')
                return
              }

							// brandStory
							result.brandStory = data[6]

							// comments
							result.comments = data[7]

							// menu
							result.menu = data[8]

							result.nameCn = data[9]

							// getMenuRecommend
							result.menuRecommend = data[10]

							uploadDetailsImgs(result)

							// let restaurant = new Restaurant(result);

							Restaurant.update({url: result.url}, result, {upsert: true}, function (err, res) {
								if (err) {
									reject(err, url)
								}
								else {
									resolve(null)
								}
							});
						}, err => {
							reject(err, url)
						})
					done();
				}
			}
		});
	})
}
